﻿using log4net;
using System.Diagnostics;
using System.Reflection;
using Koala.Pro.CodeGenerator.UI.Common;

namespace Koala.Pro.CodeGenerator.UI.DatabaseModel.Schema
{
    public class TableInfo
    {
        private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        private IDictionary<string, ColumnInfo> _columnList = new Dictionary<string, ColumnInfo>();

        private NameElement _name;

        private DatabaseInfo _databaseInfo;

        private string _scheme;

        public string Scheme
        {
            get
            {
                return _scheme;
            }
            set
            {
                _scheme = value;
            }
        }

        public NameElement Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public IDictionary<string, ColumnInfo> ColumnList
        {
            get
            {
                return _columnList;
            }
            set
            {
                _columnList = value;
            }
        }

        public DatabaseInfo DatabaseInfo
        {
            get
            {
                return _databaseInfo;
            }
            set
            {
                _databaseInfo = value;
            }
        }

        public NameElement PrimayKey
        {
            get
            {
                if (_columnList == null || _columnList.Count == 0)
                {
                    ListColumns();
                }
                NameElement nameElement = new NameElement(string.Empty);
                foreach (ColumnInfo value in _columnList.Values)
                {
                    if (value.IsPrimaryKey || value.AutoIncrement)
                    {
                        nameElement.Name = value.Name.Name;
                        nameElement.Alias = value.Name.Alias;
                        break;
                    }
                }
                return nameElement;
            }
        }

        public bool HasPirmaryKey
        {
            get
            {
                foreach (ColumnInfo value in _columnList.Values)
                {
                    if (value.IsPrimaryKey || value.AutoIncrement)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public IList<ColumnInfo> PrimaryKeyColumns
        {
            get
            {
                IList<ColumnInfo> list = new List<ColumnInfo>();
                foreach (ColumnInfo value in _columnList.Values)
                {
                    if (value.IsPrimaryKey || value.AutoIncrement)
                    {
                        list.Add(value);
                    }
                }
                return list;
            }
        }

        public int PrimaryKeyCount
        {
            get
            {
                int num = 0;
                foreach (ColumnInfo value in _columnList.Values)
                {
                    if (value.IsPrimaryKey || value.AutoIncrement)
                    {
                        num++;
                    }
                }
                return num;
            }
        }

        public bool IsMiddleTable
        {
            get
            {
                if (_columnList == null || _columnList.Count == 0)
                {
                    ListColumns();
                }
                bool flag = true;
                foreach (ColumnInfo value in _columnList.Values)
                {
                    if (!value.IsForeignKey)
                    {
                        flag = false;
                    }
                }
                if (flag)
                {
                    return _columnList.Count == 2;
                }
                return false;
            }
        }

        public IDictionary<string, ColumnInfo> ListColumns()
        {
            string database = _databaseInfo.Name.Name.ToString();
            string tableName = Name.Name.ToString();
            if (_scheme != null && _scheme.Length > 0) 
            {
                tableName = _scheme + "." + Name.Name.ToString();
            }
            ColumnList = DatabaseInfo.db.DatabaseAssembly.ListColumns(database, tableName);
            foreach (KeyValuePair<string, ColumnInfo> column in ColumnList)
            {
                column.Value.ParentTable = this;
                if (_databaseInfo.ColumnAliasHandler == null)
                {
                    _databaseInfo.ColumnAliasHandler = GetColumnAlias;
                }
                var columnName = column.Value.Name.Name.ToString();
                string text = _databaseInfo.ColumnAliasHandler(tableName, columnName, _databaseInfo.db.DatabaseType);
                if (!string.IsNullOrEmpty(text))
                {
                    column.Value.Name.Alias = new CString(text);
                    log.DebugFormat("Column {0} Alias is:{1}", column.Value.Name, text);
                }
            }
            return ColumnList;
        }

        public static string GetColumnAlias(string tableName, string columnName, string databaseType)
        {
            string result = string.Empty;
            try
            {
                var columnNameAliasInfo = ColumnNameAliasInfo.GetAliasByName(tableName, columnName, databaseType);
                if (columnNameAliasInfo != null && !string.IsNullOrEmpty(columnNameAliasInfo.ColumnAlias))
                {
                    result = columnNameAliasInfo.ColumnAlias;
                }
            }
            catch (Exception exception)
            {
                log.Error("Error when invokes GetAliasName", exception);
                throw;
            }
            return result;
        }

        public override string ToString()
        {
            return StringUtil.ToString(this);
        }
    }

}
